######################################################
# Load function

create_latex_fragment = function(etable_model_list, 
                                 variable_dictionary, 
                                 file_name, 
                                 position = "whole", 
                                 group_header = "",
                                 keep_list = "!Intercept",
                                 append_existing = FALSE, 
                                 remove_text = "", 
                                 extra_text = "", 
                                 digits = 2) {
    
    if (nchar(extra_text) != 0){
        # Write results to latex table as fragment
        etable_latex_code = etable(
            etable_model_list, 
            signif.code = c("***"=0.01, "**"=0.05, "*"=0.10), 
            fitstat = ~ n, 
            tex = TRUE, 
            dict = variable_dictionary, 
            digits = digits, 
            keep = keep_list, 
            extralines = extra_text,
            interaction.combine = "~",
            style.tex = style.tex("aer",
                                  yesNo = c("\\multicolumn{1}{c}{Yes}", "\\multicolumn{1}{c}{No}"), 
                                  stats.title = "\\midrule", 
                                  fixef.suffix = " FEs")
        )
    }
    if (nchar(extra_text) == 0){
        # Write results to latex table as fragment
        etable_latex_code = etable(
            etable_model_list, 
            signif.code = c("***"=0.01, "**"=0.05, "*"=0.10), 
            fitstat = ~ n, 
            tex = TRUE, 
            dict = variable_dictionary, 
            digits = digits, 
            keep = keep_list, 
            interaction.combine = "~",
            style.tex = style.tex("aer",
                                  yesNo = c("\\multicolumn{1}{c}{Yes}", "\\multicolumn{1}{c}{No}"), 
                                  stats.title = "\\midrule", 
                                  fixef.suffix = " FEs")
        )
    }
    # Remove top and bottom rows.
    etable_latex_code = etable_latex_code[-length(etable_latex_code)]
    etable_latex_code = etable_latex_code[-1]
    
    # Fix centering issue for the top row when using si-units 
    m_split = "\\multicolumn{1}{c}{("
    m_info = 1:length(etable_model_list)
    m_right = ")}"
    model_format = paste0(m_split[1], m_info, m_right)
    model_line = paste0(" & ", paste0(model_format, collapse = " & "), "\\\\\n")
    
    # Replace first line with the new "model_line"
    etable_latex_code = etable_latex_code[-1]
    etable_latex_code[1] = model_line
    
    # Remove commas in coef/se numbers (by removing commas if there's a number on either side)
    etable_latex_code = gsub(",([0-9])", "\\1", etable_latex_code)
    
    # Fix centering issue for the observations row when using si-units
    n_split = "\\multicolumn{1}{c}{"
    n_info = sapply(etable_model_list, nobs)
    n_info = format(n_info, big.mark=",", scientific=FALSE, trim=TRUE)
    n_right = "}"
    n_format = paste0(n_split[1], n_info, n_right)
    n_line = paste0("Observations & ", paste0(n_format, collapse = " & "), "\\\\\n")
    
    # Identify line in latex_table that is current observations using startsWith and then replace
    etable_latex_code[startsWith(etable_latex_code, "Observations") == TRUE] = n_line
    
    # Remove skipping of lines
    etable_latex_code = etable_latex_code %>% str_remove("\n")
    
    ####################################################################
    # Create "top" panel
    if (position == "top") {
        # Identify where "Observations" line starts
        logical_starts_with_midrule = startsWith(etable_latex_code, "   \\midrule") == TRUE
        logical_starts_with_obs = startsWith(etable_latex_code, "   Observations") == TRUE 
        logical_starts_with_both = (logical_starts_with_midrule == TRUE | logical_starts_with_obs == TRUE) & lead((logical_starts_with_midrule == TRUE | logical_starts_with_obs == TRUE)) ==TRUE
        
        position_of_end_table = which(logical_starts_with_both %in% TRUE)
        
        etable_latex_code = etable_latex_code[1:(position_of_end_table-1)]
        
        if (nchar(group_header) != 0) {
            
            # Add line end and column separators
            group_header = paste0(group_header, 
                                  paste(rep(" &", length(etable_model_list)), sep="", collapse=""),
                                  "\\\\\n")
            
            etable_latex_code = append(etable_latex_code, group_header, after = 2)
        }
    }
    
    ####################################################################
    # Create "middle" panel
    if (position == "middle") {
        # Identify where "Observations" line starts
        logical_starts_with_midrule = startsWith(etable_latex_code, "   \\midrule") == TRUE
        logical_starts_with_obs = startsWith(etable_latex_code, "   Observations") == TRUE 
        logical_starts_with_both = (logical_starts_with_midrule == TRUE | logical_starts_with_obs == TRUE) & lead((logical_starts_with_midrule == TRUE | logical_starts_with_obs == TRUE)) ==TRUE
        
        position_of_end_table = which(logical_starts_with_both %in% TRUE)
        
        # Identify where "midrule" line starts
        logical_starts_with_multicolumn = startsWith(etable_latex_code, "    & \\multicolumn") == TRUE 
        logical_starts_with_both = (logical_starts_with_midrule == TRUE | logical_starts_with_multicolumn == TRUE) & lag((logical_starts_with_midrule == TRUE | logical_starts_with_multicolumn == TRUE), 2) ==TRUE
        
        position_of_start_table = which(logical_starts_with_both %in% TRUE)
        
        etable_latex_code = etable_latex_code[(position_of_start_table+1):(position_of_end_table-1)]
        
        if (nchar(group_header) != 0) {
            # Add line end and column separators
            group_header = paste0(group_header, 
                                  paste(rep(" &", length(etable_model_list)), sep="", collapse=""),
                                  "\\\\\n")
            etable_latex_code = append(etable_latex_code, group_header, after = 0)
        }
    }
    
    ####################################################################
    # Create "bottom" panel
    if (position == "bottom") {
        # Identify where "midrule" line starts
        logical_starts_with_multicolumn = startsWith(etable_latex_code, "    & \\multicolumn") == TRUE 
        logical_starts_with_midrule = startsWith(etable_latex_code, "   \\midrule") == TRUE
        logical_starts_with_both = (logical_starts_with_midrule == TRUE | logical_starts_with_multicolumn == TRUE) & lag((logical_starts_with_midrule == TRUE | logical_starts_with_multicolumn == TRUE), 2) == TRUE
        
        position_of_start_table = which(logical_starts_with_both %in% TRUE)
        
        etable_latex_code = etable_latex_code[(position_of_start_table+1):length(etable_latex_code)]
        
        if (nchar(group_header) != 0) {
            # Add line end and column separators
            group_header = paste0(group_header, 
                                  paste(rep(" &", length(etable_model_list)), sep="", collapse=""),
                                  "\\\\\n")
            etable_latex_code = append(etable_latex_code, group_header, after = 0)
        }
    }
    
    if (nchar(remove_text) != 0) {
        etable_latex_code = etable_latex_code %>% str_remove_all(remove_text)
    }

    # Write to disk
    write(etable_latex_code, 
          file = file_name, 
          append = append_existing)
    
    return(etable_latex_code)
} 